package com.linkdood.app.web.rest;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.linkdood.app.domain.Account;
import com.linkdood.app.dto.AccountDTO;
import com.linkdood.app.dto.PasswordDTO;
import com.linkdood.app.dto.PhoneCodeDTO;
import com.linkdood.app.dto.ResetPasswordDTO;
import com.linkdood.app.exception.UserNotFoundException;
import com.linkdood.app.service.AccountService;
import com.linkdood.app.service.AuthorityService;
import com.linkdood.app.utils.PaginationUtil;
import com.linkdood.app.utils.ResourceUtil;
import com.linkdood.app.vm.AccountVM;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * 系统用户接口
 *
 * @author YunJ
 */
@Api(value = "系统用户接口", tags = {"系统用户接口"})
@Slf4j
@RestController
@RequestMapping("/api/accounts")
public class AccountResource {

    private final AuthorityService authorityService;
    private final AccountService accountService;

    public AccountResource(AuthorityService authorityService, AccountService accountService) {
        this.authorityService = authorityService;
        this.accountService = accountService;
    }

    @ApiOperation(value = "获取当前登录用户的信息")
    @GetMapping("/me")
    public ResponseEntity<?> getCurrentUserInfo() {
        AccountVM userAccount = accountService.getCurrentAccountInfo();
        return ResponseEntity.ok(userAccount);
    }

    @ApiOperation(value = "重置用户的密码")
    @PatchMapping("/reset/{id}")
    public ResponseEntity<?> updateAccount(@PathVariable String id) {
        accountService.resetPassword(id);
        return ResponseEntity.ok(ResourceUtil.success());
    }

    @ApiOperation(value = "获取指定 id 的用户信息")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "query", name = "id", value = "用户 id", required = true, dataType = "String")})
    @GetMapping("/{id}")
    public ResponseEntity<?> getUser(@PathVariable String id) {
        Account result = accountService.getById(id);
        if (result == null) {
            throw new UserNotFoundException();
        }
        return ResponseEntity.ok(result);
    }
    @PreAuthorize("@ss.hasPermi('bxy:user:index')")
    @ApiOperation(value = "查询用户信息", notes = "查询条件可以组合使用")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "query", name = "name", value = "用户名", dataType = "String")})
    @GetMapping
    public ResponseEntity<?> getUsers(@RequestParam(value = "displayName", required = false) String displayName,
                                      @RequestParam(value = "role", required = false) String role,
                                      @RequestParam(value = "username", required = false) String username,
                                      Pageable pageable) {
        Page<AccountVM> page = accountService.pageAccounts(displayName, role, username, PaginationUtil.getPage(pageable));
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page);
        return new ResponseEntity<>(page.getRecords(), headers, HttpStatus.OK);
    }
    @PreAuthorize("@ss.hasPermi('bxy:user:delete')")
    @ApiOperation(value = "删除指定 id 的用户")
    @DeleteMapping("/{id}")
    public ResponseEntity<?> deleteUser(@PathVariable Long id) {
        accountService.removeById(id);
        // 删除用户角色关联表
        authorityService.deleteAccountRole(String.valueOf(id));
        return ResponseEntity.ok(ResourceUtil.success());
    }
    @PreAuthorize("@ss.hasPermi('bxy:user:add')")
    @ApiOperation(value = "新增系统用户")
    @PostMapping()
    public ResponseEntity<?> createUser(@RequestBody AccountDTO account) {
        AccountVM accountVm = accountService.saveAccount(account);
        return ResponseEntity.ok(accountVm);
    }
    @PreAuthorize("@ss.hasPermi('bxy:user:edit')")
    @ApiOperation(value = "修改系统用户信息")
    @PatchMapping("/{id}")
    public ResponseEntity<?> updateUser(@PathVariable String id, @RequestBody AccountDTO account) {
        AccountVM accountVm = accountService.update(id, account);
        return ResponseEntity.ok(accountVm);
    }

    @PreAuthorize("@ss.hasPermi('bxy:user:resetPwd')")
    @ApiOperation(value = "修改用户的密码")
    @PatchMapping("/password")
    public ResponseEntity<?> updateAccount(@RequestBody PasswordDTO passwordDTO) {
        Account currentAccount = accountService.getCurrentAccount();
        AccountVM accountVm = new AccountVM();
        if (currentAccount != null) {
            accountVm = accountService.updateAccountPassword(currentAccount, passwordDTO);
        }
        return ResponseEntity.ok(accountVm);
    }

    @ApiOperation(value = "校验用户名是否存在")
    @PostMapping("/exist")
    public ResponseEntity<?> exist(@RequestBody AccountDTO req) {
        boolean isExist = accountService.accountIsExist(req.getUsername());
        Map<String, Boolean> result = new HashMap<>(1);
        result.put("exist", isExist);
        return ResponseEntity.ok(result);
    }

    @ApiOperation(value = "设置新密码(忘记密码)")
    @PostMapping("/new-password")
    public ResponseEntity<?> newPassword(@Valid @RequestBody ResetPasswordDTO req) {
        accountService.newPassword(req);
        return ResponseEntity.ok(ResourceUtil.success());
    }

    @ApiOperation(value = "修改用户名(手机号)")
    @PatchMapping("/username/{id}")
    public ResponseEntity<?> updateUserName(@PathVariable String id, @Valid @RequestBody PhoneCodeDTO req) {
        accountService.updateUserName(id, req);
        return ResponseEntity.ok(ResourceUtil.success());
    }
}
